﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.IO;
using System.IO.IsolatedStorage;
using Newtonsoft.Json;
using Microsoft.Phone.Controls.Primitives;
using System.Windows.Controls.Primitives;
using System.Collections.ObjectModel;

namespace MeetingFinder
{
    public partial class MainPage : PhoneApplicationPage
    {
        private string userID = null;
        private string selectedNotificationItemID = null;
        Popup SplashScreenPopup;

        public MainPage()
        {
            var currentApp = App.Current as App;

            SplashScreenPopup = new Popup() { IsOpen = true, Child = new SplashScreenPopup() };

            //get userID from isolated store
            
            userID = GetUserID();
            currentApp._userID = userID;

            //getting confirmed meeting items and adding to list
            WebClient getConfirmedMeetingProxy = new WebClient();
            getConfirmedMeetingProxy.DownloadStringCompleted += (senderC, eC) =>
            {
                if (eC.Error == null)
                {
                    string result = eC.Result;
                    var serverItemList = JsonConvert.DeserializeObject<List<ServerMeetingItem>>(result);


                    currentApp._meetingItemList = new List<MeetingItem>();
                    foreach (ServerMeetingItem serverMeetingItem in serverItemList)
                    {
                        MeetingItem meeting = new MeetingItem();
                        meeting.convertToMeetingItem(serverMeetingItem, MeetingItem.Status.Confirmed);
                        currentApp._meetingItemList.Add(meeting);
                    }

                    //getting pending meeting items and adding to list
                    WebClient getPendingMeetingProxy = new WebClient();
                    getPendingMeetingProxy.DownloadStringCompleted += (senderP, eP) =>
                    {
                        if (eP.Error == null)
                        {
                            result = eP.Result;
                            serverItemList = JsonConvert.DeserializeObject<List<ServerMeetingItem>>(result);

                            foreach (ServerMeetingItem serverMeetingItem in serverItemList)
                            {
                                MeetingItem meeting = new MeetingItem();
                                meeting.convertToMeetingItem(serverMeetingItem, MeetingItem.Status.Pending);
                                currentApp._meetingItemList.Add(meeting);
                            }

                            //getting updated meeting items and adding to list
                            WebClient getUpdatedMeetingProxy = new WebClient();
                            getUpdatedMeetingProxy.DownloadStringCompleted += (senderU, eU) =>
                            {
                                if (eU.Error == null)
                                {

                                    result = eU.Result;
                                    serverItemList = JsonConvert.DeserializeObject<List<ServerMeetingItem>>(result);

                                    foreach (ServerMeetingItem serverMeetingItem in serverItemList)
                                    {
                                        MeetingItem meeting = new MeetingItem();
                                        meeting.convertToMeetingItem(serverMeetingItem, MeetingItem.Status.Updated);
                                        currentApp._meetingItemList.Add(meeting);
                                    }

                                    //getting new meeting items and adding to list
                                    WebClient getNewMeetingProxy = new WebClient();
                                    getNewMeetingProxy.DownloadStringCompleted += (senderNM, eNM) =>
                                    {
                                        if (eNM.Error == null)
                                        {

                                            result = eNM.Result;
                                            serverItemList = JsonConvert.DeserializeObject<List<ServerMeetingItem>>(result);

                                            foreach (ServerMeetingItem serverMeetingItem in serverItemList)
                                            {
                                                MeetingItem meeting = new MeetingItem();
                                                meeting.convertToMeetingItem(serverMeetingItem, MeetingItem.Status.Updated);
                                                meeting._newMeetingStatus = "new";
                                                currentApp._meetingItemList.Add(meeting);
                                            }

                                            //getting notification items and adding to list
                                            WebClient getNotificationProxy = new WebClient();
                                            getNotificationProxy.DownloadStringCompleted += (senderN, eN) =>
                                            {
                                                if (eN.Error == null)
                                                {
                                                    result = eN.Result;

                                                    currentApp._notificationItemList = JsonConvert.DeserializeObject<ObservableCollection<ServerNotificationItem>>(result);

                                                    //searching main list and setting the group id as group name for now
                                                    foreach (ServerNotificationItem notificationItem in currentApp._notificationItemList)
                                                    {
                                                        for (int i = 0; i < currentApp._meetingItemList.Count; i++)
                                                            if (currentApp._meetingItemList[i]._meetingItemID == notificationItem._meetingId)
                                                                notificationItem._groupName = currentApp._meetingItemList[i]._groupID;
                                                    }

                                                    //getting unread notification items and adding to list
                                                    WebClient getUnreadNotificationProxy = new WebClient();
                                                    getUnreadNotificationProxy.DownloadStringCompleted += (senderUN, eUN) =>
                                                    {
                                                        if (eUN.Error == null)
                                                        {
                                                            result = eUN.Result;
                                                            currentApp._unreadNotificationItemList = JsonConvert.DeserializeObject<ObservableCollection<ServerNotificationItem>>(result);

                                                            //searching main list and setting the group id as group name for now
                                                            foreach (ServerNotificationItem notificationItem in currentApp._unreadNotificationItemList)
                                                            {
                                                                for (int i = 0; i < currentApp._meetingItemList.Count; i++)
                                                                    if (currentApp._meetingItemList[i]._meetingItemID == notificationItem._meetingId)
                                                                        notificationItem._groupName = currentApp._meetingItemList[i]._groupID;
                                                            }

                                                            //getting History items and add to list
                                                            WebClient getHistoryProxy = new WebClient();
                                                            getHistoryProxy.DownloadStringCompleted += (senderH, eH) =>
                                                            {
                                                                if (eH.Error == null)
                                                                {
                                                                    result = eH.Result;
                                                                    serverItemList = JsonConvert.DeserializeObject<List<ServerMeetingItem>>(result);

                                                                    currentApp._historyItemList = new List<MeetingItem>();
                                                                    foreach (ServerMeetingItem serverMeetingItem in serverItemList)
                                                                    {
                                                                        MeetingItem meeting = new MeetingItem();
                                                                        meeting.convertToMeetingItem(serverMeetingItem, MeetingItem.Status.History);
                                                                        currentApp._historyItemList.Add(meeting);
                                                                    }

                                                                    //required lists have been pulled from server, now initialize elements on main page
                                                                    InitializeComponent();

                                                                    InitializeApplicationBar();

                                                                    AddButtonToAppBar(StringConstants._addIconPath, StringConstants._appBarCreateNewMeetingIconText, CreateMeetingButton_Click);
                                                                    AddMenuItemToAppBar(StringConstants._appBarLogoutMenueItemText, LogoutMenuItem_Click);

                                                                    InitializeLocaLists();

                                                                    SplashScreenPopup.IsOpen = false;
                                                                }
                                                            };//end history list
                                                            getHistoryProxy.DownloadStringAsync(new Uri(StringConstants._serverAddress + StringConstants._getHistoryAPI + currentApp._userID, UriKind.Absolute));
                                                        }
                                                    };//end unread notification list
                                                    getUnreadNotificationProxy.DownloadStringAsync(new Uri(StringConstants._serverAddress + StringConstants._getUnreadNotificationAPI + currentApp._userID, UriKind.Absolute));
                                                }
                                            };//end notification list

                                            getNotificationProxy.DownloadStringAsync(new Uri(StringConstants._serverAddress + StringConstants._getNotificationAPI + currentApp._userID, UriKind.Absolute));
                                        }
                                    };//end new meeting list
                                    getNewMeetingProxy.DownloadStringAsync(new Uri(StringConstants._serverAddress + StringConstants._getNewAPI + currentApp._userID, UriKind.Absolute));
                                }
                            };//end updated list

                            getUpdatedMeetingProxy.DownloadStringAsync(new Uri(StringConstants._serverAddress + StringConstants._getUpdatedAPI + currentApp._userID, UriKind.Absolute));
                        }
                    };//end pending list


                    getPendingMeetingProxy.DownloadStringAsync(new Uri(StringConstants._serverAddress + StringConstants._getPendingAPI + currentApp._userID, UriKind.Absolute));

                }
            };//end confirmed list
            getConfirmedMeetingProxy.DownloadStringAsync(new Uri(StringConstants._serverAddress + StringConstants._getConfirmedAPI + currentApp._userID, UriKind.Absolute));

        }


//Private / Helper Methods----------------------------------------------------------------------------------

        //creates new instance of Application bar
        private void InitializeApplicationBar()
        {
            ApplicationBar = new ApplicationBar();

            ApplicationBar.Mode = ApplicationBarMode.Default;
            ApplicationBar.Opacity = 0.8;
            ApplicationBar.IsVisible = true;
            ApplicationBar.IsMenuEnabled = true;
            //ApplicationBar.BackgroundColor = new Color() { A = 0, R = 0, G = 255, B = 0 }; 
        }

        //crates a new button on application bar
        //sets icon image
        //set click even handler
        private void AddButtonToAppBar(String IconPath, String DescriptionText, EventHandler ClickEventHandler)
        {
            ApplicationBarIconButton CreateNewMeetingButton = new ApplicationBarIconButton();
            CreateNewMeetingButton.IconUri = new Uri(IconPath, UriKind.Relative);
            CreateNewMeetingButton.Text = DescriptionText;
            ApplicationBar.Buttons.Add(CreateNewMeetingButton);
            CreateNewMeetingButton.Click += new EventHandler(ClickEventHandler);
        }

        //create AppBar menuItem
        private void AddMenuItemToAppBar(String DescriptionText, EventHandler ClickEventHandler)
        {
            ApplicationBarMenuItem MenuItem = new ApplicationBarMenuItem();
            MenuItem.Text = DescriptionText;
            ApplicationBar.MenuItems.Add(MenuItem);
            MenuItem.Click += new EventHandler(ClickEventHandler);
        }

        //test function to set userID
        private void SetUserID(string userID)
        {
            IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication();

            //create new file
            using (StreamWriter writeFile = new StreamWriter(new IsolatedStorageFileStream("UserID.txt", FileMode.Create, FileAccess.Write, myIsolatedStorage)))
            {
                string someTextData = userID;
                writeFile.WriteLine(someTextData);
                writeFile.Close();
            }
        }

        //clear userID isolatedStorage
        //this removes the Group data that is stored in there as well
        private void ClearUserID()
        {
            IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication();

            //overwrite file
            using (myIsolatedStorage)
            {
                if (myIsolatedStorage.FileExists(StringConstants._userIDStorage))
                    myIsolatedStorage.DeleteFile(StringConstants._userIDStorage);
            }

        }

        //reads userID from text file in isolated storage
        private string GetUserID()
        {
            string userID;
            try
            {
                IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication();
                IsolatedStorageFileStream fileStream = myIsolatedStorage.OpenFile("UserID.txt", FileMode.Open, FileAccess.Read);

                using (StreamReader reader = new StreamReader(fileStream))
                {    //Visualize the text data in a TextBlock text
                    userID = reader.ReadLine();
                    string projectGroupDetails = reader.ReadLine();
                    setProjectGroupList(projectGroupDetails);
                }
            }
            catch (IsolatedStorageException ex)
            {
                userID = "UserID.txt does not exist";
            }
            return userID;
        }

        private void setProjectGroupList(string projectGroupString)
        {
            var received = App.Current as App;

            List<ProjectGroup> projectGroupList = new List<ProjectGroup>();

            string[] groupArry = projectGroupString.Split('#');

            List<string> groupString = new List<string>();

            //remove empty string
            foreach (string item in groupArry)
                if (item != "")
                    groupString.Add(item);

            foreach (string group in groupString)
            {
                var details = group.Split(',');
                ProjectGroup projectGroup = new ProjectGroup();
                projectGroup._groupName = details[0];
                projectGroup._moduleCode = details[1];
                projectGroup._projectName = details[2];
                projectGroup._numOfGroupMembers = details[3];
                projectGroup._groupID = details[4];

                projectGroupList.Add(projectGroup);
            }

            received._projectGroupList = projectGroupList;
        }

        //Sends initializes local Lists 
        private void InitializeLocaLists()
        {
            //initializing meeting list for Main Page Pivot
            var received = App.Current as App;

            var meetingByStatus = from meeting in received._meetingItemList
                                    group meeting by meeting._meetingStatus into m
                                    orderby m.Key
                                    select new Group<MeetingItem>(m.Key.ToString(), m);
            this.meetingList.ItemsSource = meetingByStatus; 

            //initialize project group list
            //received._projectGroupList = CreateProjectGroupTestList();

            //initialize History List
            var historyByGroup = from historyItem in received._historyItemList
                                 group historyItem by historyItem._groupName into h
                                  orderby h.Key
                                  select new Group<MeetingItem>(h.Key, h);
            this.historyList.ItemsSource = historyByGroup; 

            //initizlize Notification list
            this.notificationList.ItemsSource = received._notificationItemList; 

            //initialize unread Notification list
            this.unreadNotificationList.ItemsSource = received._unreadNotificationItemList;
        }
        
        //just creates a list for testing, get actual list from a main store, may be dict
        private List<ProjectGroup> CreateProjectGroupTestList()
        {
            List<ProjectGroup> testList = new List<ProjectGroup>();

            for (int i = 0; i < 5; i++)
            {
                ProjectGroup group = new ProjectGroup();
                group._groupName = "Group " + i;
                group._moduleCode = "Module " + i + i;

                testList.Add(group);
            }
            return testList;
        }

        private void exit()
        {
            throw new Exception("Exit");
        }


//event handlers---------------------------------------------------------------------------------------------

        private void LoginToIVLEButton_Click(object sender, EventArgs e)
        {
            // navigate
            this.NavigationService.Navigate(new Uri("/IVLElogin.xaml", UriKind.Relative));
        }

        private void LandingPage_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            switch (((Pivot)sender).SelectedIndex)
            {
                case 0:
                    ApplicationBar.IsVisible = true;
                    break;

                case 1:
                    ApplicationBar.IsVisible = false;
                    break;

                case 2:
                    ApplicationBar.IsVisible = false;
                    break;
            }
        }

        private void CreateMeetingButton_Click(object sender, EventArgs e)
        {
            if (userID == "UserID.txt does not exist" || userID == "")
                this.NavigationService.Navigate(new Uri("/IVLElogin.xaml", UriKind.Relative));
            else
                this.NavigationService.Navigate(new Uri("/GroupSelection.xaml", UriKind.Relative));
        }

        //logout menuItem even handler
        private void LogoutMenuItem_Click(object sender, EventArgs e)
        {
            //clear UserID isolated Storage File
            ClearUserID();

            //set userID to null
            var current = App.Current as App;
            current._userID = null;

            //show popup and exist application
            Popup popup = new Popup();
            popup.Height = 300;
            popup.Width = 400;
            popup.VerticalOffset = 100;
            MainPagePopup control = new MainPagePopup();
            popup.Child = control;
            popup.IsOpen = true;

            control.messageBox.Text = "You have been Logged out. \n\t see you soon :)";

            control.btnOK.Click += (s, args) =>
            {
                popup.IsOpen = false;
                exit();

            };
        }

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            var current = App.Current as App;

            //userID = GetUserID();
            if (userID == "UserID.txt does not exist" || userID == "" || userID[0] != 'u' || userID.Length != 8)
                this.NavigationService.Navigate(new Uri("/IVLElogin.xaml", UriKind.Relative));
            else
                current._userID = userID;
        }

        private void historyList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var toSend = App.Current as App;

            MeetingItem selectedHistoryItem = (MeetingItem)this.historyList.SelectedItem;
            toSend._historyItemSelected = selectedHistoryItem;
            this.historyList.UpdateLayout();
            //this.NavigationService.Navigate(new Uri("/ViewHistory.xaml", UriKind.Relative));
        }

        private void meetingList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var toSend = App.Current as App;

            MeetingItem selectedNotificationItem = (MeetingItem)this.meetingList.SelectedItem;
            toSend._editFormItemSelected = selectedNotificationItem;
            //this.NavigationService.Navigate(new Uri("/EditMeetingForm.xaml?notificationid=notnotification", UriKind.Relative));
        }

        private void unreadNotificationList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var toSend = App.Current as App;

            ServerNotificationItem selectedNotificationItem = (ServerNotificationItem)this.unreadNotificationList.SelectedItem;

            if (selectedNotificationItem != null)
            {
                //search for the meeting in main list and set it as the selected meeting
                foreach (MeetingItem meetingItem in toSend._meetingItemList)
                    if (meetingItem._meetingItemID == selectedNotificationItem._meetingId)
                        toSend._editFormItemSelected = meetingItem;

                selectedNotificationItemID = selectedNotificationItem._id;
                //this.NavigationService.Navigate(new Uri("/EditMeetingForm.xaml?notificationid=" + selectedNotificationItem._id, UriKind.Relative));
            }

        }

        private void notificationList_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
        {
            var toSend = App.Current as App;

            ServerNotificationItem selectedNotificationItem = (ServerNotificationItem)this.notificationList.SelectedItem;

            if (selectedNotificationItem != null)
            {
                //search for the meeting in main list and set it as the selected meeting
                foreach (MeetingItem meetingItem in toSend._meetingItemList)
                    if (meetingItem._meetingItemID == selectedNotificationItem._meetingId)
                        toSend._editFormItemSelected = meetingItem;

                selectedNotificationItemID = selectedNotificationItem._id;
                this.NavigationService.Navigate(new Uri("/EditMeetingForm.xaml?notificationid=" + selectedNotificationItem._id, UriKind.Relative));
            }

        }

        private void historyList_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            this.NavigationService.Navigate(new Uri("/ViewHistory.xaml", UriKind.Relative));
        }

        private void unreadNotificationList_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            this.NavigationService.Navigate(new Uri("/EditMeetingForm.xaml?notificationid=" + selectedNotificationItemID, UriKind.Relative));
        }

        private void notificationList_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            this.NavigationService.Navigate(new Uri("/EditMeetingForm.xaml?notificationid=" + selectedNotificationItemID, UriKind.Relative));
        }

        private void meetingList_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            this.NavigationService.Navigate(new Uri("/EditMeetingForm.xaml?notificationid=notnotification", UriKind.Relative));
        }

    }
}